package com.lhf.novel.sysuser.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lhf.novel.event.MailEvent;
import com.lhf.novel.sysuser.dao.SysUserRoleDao;
import com.lhf.novel.sysuser.entity.SysUser;
import com.lhf.novel.sysuser.dao.SysUserDao;
import com.lhf.novel.sysuser.po.LoginPo;
import com.lhf.novel.sysuser.service.SysUserService;
import com.lhf.novel.sysuser.vo.SysUserInfoVo;
import com.lhf.novel.sysuser.vo.SysUserVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * (SysUser)表服务实现类
 *
 * @author 刘会发
 * @since 2020-03-09 11:19:26
 */
@Service("sysUserService")
public class SysUserServiceImpl implements SysUserService {
    private static final Logger LOGGER = LoggerFactory.getLogger(SysUserServiceImpl.class);
    @Resource
    private SysUserDao sysUserDao;
    @Resource
    private SysUserRoleDao sysUserRoleDao;
    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Resource
    private ApplicationContext applicationContext;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public SysUserInfoVo queryById(Integer id) {
        return this.sysUserDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<SysUser> queryAllByLimit(int offset, int limit) {
        return this.sysUserDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @return 实例对象
     */
    @Override
    @Transactional
    public Boolean insert(String username, String realName, String email, String phone, Integer isLock, String password, String roles) throws MessagingException {
        if (StringUtils.isBlank(password)) {
            password = "123456";
        }
        SysUser sysUser = new SysUser(username, realName, email, phone, isLock, bCryptPasswordEncoder.encode(password));
        this.sysUserDao.insert(sysUser);
        Integer[] array = null;
        if (StringUtils.isBlank(roles)) {
            array = new Integer[]{3};
        } else {
            JSONArray objects = JSONArray.parseArray(roles);
            array = objects.toArray(new Integer[objects.size()]);
        }
        if (sysUserRoleDao.insert(sysUser.getId(), array) > 0) {
            String builder = "<body>" +
                    "<h4>点击下方按钮激活账号</h4>" +
                    "<a href='http://localhost:2626/sysUser/activate?id=" + sysUser.getId() + "'>点击激活</a>" +
                    "</body>";
            applicationContext.publishEvent(new MailEvent(this, email, "用户激活", builder));
            LOGGER.info("发送激活邮件,激活的用户=======" + sysUser.getUsername());
            return true;
        }
        return false;
    }

    /**
     * 修改数据
     *
     * @param sysUser 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public SysUserInfoVo update(SysUser sysUser, String ridJson) throws IllegalAccessException {
        if (sysUser.getId() == null)
            throw new IllegalAccessException("用户id不能为空");
        if (StringUtils.isEmpty(sysUser.getRealName()) &&
                StringUtils.isEmpty(sysUser.getEmail()) &&
                StringUtils.isEmpty(sysUser.getPhone()) &&
                StringUtils.isEmpty(sysUser.getHeadImg()) &&
                sysUser.getIsLock() == null &&
                StringUtils.isEmpty(ridJson) &&
                sysUser.getIsDel() == null)
            throw new IllegalAccessException("至少修改一个字段");
        System.out.println(StringUtils.isEmpty(ridJson));
        if (StringUtils.isNotBlank(ridJson)) {
            JSONArray jsonArray = JSONArray.parseArray(ridJson);
            Integer[] rids = jsonArray.toArray(new Integer[jsonArray.size()]);
            if (rids.length > 0) {
                sysUserRoleDao.delete(sysUser.getId());
                sysUserRoleDao.insert(sysUser.getId(), rids);
            }
        }
        this.sysUserDao.update(sysUser);
        return this.queryById(sysUser.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.sysUserDao.deleteById(id) > 0;
    }

    /**
     * 查询所有
     *
     * @param username 用户名
     * @param realName 真实名字
     * @param email    邮件地址
     * @param phone    手机号
     * @param isLock   是否锁定
     * @param pageNum  页码
     * @param pageSize 每页展示数量
     * @return
     */
    @Override
    public PageInfo<SysUserVo> queryAll(String username, String realName, String email, String phone, Integer isLock, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return PageInfo.of(sysUserDao.queryAll(new SysUser(username, realName, email, phone, isLock)));
    }

    @Override
    public void activate(Integer id) throws IllegalAccessException {
        LOGGER.info("用户激活:" + id + "激活时间:" + new Date());
        this.update(new SysUser(id, 0), null);
    }

    @Override
    public Integer updatePassword(String oldVal, String newVal, HttpServletRequest request) throws IllegalAccessException {
        String uidStr = (String) request.getSession().getAttribute("uid");
        Integer uid = Integer.getInteger(uidStr);

        SysUserInfoVo sysUser = this.queryById(uid);

//        String encode = bCryptPasswordEncoder.encode(oldVal);
        if (bCryptPasswordEncoder.matches(oldVal, sysUser.getPassword())) {
            this.update(new SysUser(uid, bCryptPasswordEncoder.encode(newVal)), null);
            return 1;
        } else {
            return 0;//密码错误
        }
    }

    @Override
    public Integer authorization(Integer uid, String jsonRoles) {
        JSONArray objects = JSONObject.parseArray(jsonRoles);
        Integer[] roles = objects.toArray(new Integer[objects.size()]);
        sysUserRoleDao.insert(uid, roles);
        return 1;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LoginPo login = sysUserDao.login(username);
        if (login == null)
            throw new UsernameNotFoundException("用户未找到");
        return login;
    }

    /**
     * <p>查询用户名是否存在</p>
     *
     * @param username
     * @return
     */
    @Override
    public boolean isExistForUsername(String username) {
        return sysUserDao.isExistForUsername(username) == 0;
    }
}